﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace CSharpHelpers.IOs
{
    /// <summary>
    /// ini文件的读写和锁帮助类
    /// </summary>
    class IniUtil
    {
        // private string filePath;
        private bool flag;
        public IniUtil()
        {
            //this.filePath = filePath;
        }

        #region 调用windowsAPI
        [DllImport("Kernel32.dll")]
        private static extern int GetPrivateProfileString(string strAppName, string strKeyName, string strDefault, StringBuilder sbReturnString, int nSize, string strFileName);
        [DllImport("Kernel32.dll")]
        private extern static int GetPrivateProfileStringA(string strAppName, string strKeyName, string sDefault, byte[] buffer, int nSize, string strFileName);
        [DllImport("Kernel32.dll")]
        private static extern int GetPrivateProfileInt(string strAppName, string strKeyName, int nDefault, string strFileName);

        //获取ini文件所有的section
        [DllImport("Kernel32.dll")]
        private extern static int GetPrivateProfileSectionNamesA(byte[] buffer, int iLen, string fileName);

        //获取指定Section的key和value        
        [DllImport("Kernel32.dll")]
        private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString, int nSize, string lpFileName);

        //根据传入参数的不同进行写入或修改或删除操作（返回值 Long，非零表示成功，零表示失败）
        [DllImport("Kernel32.dll")]
        public static extern long WritePrivateProfileString(string strAppName, string strKeyName, string strKeyValue, string strFileName);

        //添加一个section内容列表
        [DllImport("Kernel32.dll")]
        public static extern long WritePrivateProfileSection(string strAppName, string strkeyandvalue, string strFileName);
        #endregion

        #region Advanced Function
        /// <summary>
        /// ini的读取
        /// </summary>
        /// <param name="sectionList"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public Dictionary<string, Dictionary<string, string>> ReadSections(ArrayList sectionList, string filePath)
        {
            Dictionary<string, Dictionary<string, string>> NodeList = new Dictionary<string, Dictionary<string, string>>();
            foreach (string str in sectionList)
            {
                NodeList.Add(str, GetIniSectionValue(str, filePath));
            }
            return NodeList;

        }

        /// <summary>
        /// BetLimit的读取
        /// 如果Section的key名最后带下画线就去掉下画线
        /// </summary>
        /// <param name="sectionList"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public Dictionary<string, Dictionary<string, string>> ReadBetLimitSections(ArrayList sectionList, string filePath)
        {
            Dictionary<string, Dictionary<string, string>> NodeList = new Dictionary<string, Dictionary<string, string>>();
            foreach (string str in sectionList)
            {
                NodeList.Add(str, GetBetLimitSectionValue(str, filePath));
            }
            return NodeList;

        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="dictionary">ini集合</param>
        public Boolean AddSection(Dictionary<string, Dictionary<string, string>> dictionary, string filePath)
        {
            try
            {
                foreach (string str in dictionary.Keys)
                {
                    foreach (KeyValuePair<string, string> dic in dictionary[str])
                    {
                        EditIniKey(str, dic.Key, dic.Value, filePath);
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                FileLog.LogError(e);
                return false;
            }

        }
        /// <summary>
        /// BetLimitSection保存,此方法比较特别
        /// 如果Section的key的值=0,key的名字就加下画线
        /// 大于0时取消下画线
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public Boolean AddBetLimitSection(Dictionary<string, Dictionary<string, string>> dictionary, string filePath)
        {
            try
            {
                foreach (string str in dictionary.Keys)
                {
                    foreach (KeyValuePair<string, string> dic in dictionary[str])
                    {
                        string keyStr = dic.Key;
                        if (dic.Value.Equals("0"))
                        {
                            DeleteIniKey(str, dic.Key, filePath);//根据KEY删除
                            keyStr = dic.Key + "_";//添加一个带下画线的
                        }
                        else
                        {
                            DeleteIniKey(str, dic.Key + "_", filePath);//根据KEY删除                            
                        }

                        EditIniKey(str, keyStr, dic.Value, filePath);
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                FileLog.LogError(e);
                return false;
            }
        }
        #endregion

        #region Basic Function
        //判断该ini文件是否存在如果不存在新建一个该文件
        public void FileExists(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    using (FileStream fs = File.Create(filePath))
                    {
                        fs.Close();
                    }
                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                FileLog.LogError(e);
            }
        }
        //返回该配置文件中所有Section名称的集合
        public ArrayList ReadSections(string filePath)
        {
            byte[] buffer = new byte[65535];
            int rel = GetPrivateProfileSectionNamesA(buffer, buffer.GetUpperBound(0), filePath);

            int iCnt, iPos;
            ArrayList arrayList = new ArrayList();
            string tmp;
            if (rel > 0)
            {
                iCnt = 0; iPos = 0;
                for (iCnt = 0; iCnt < rel; iCnt++)
                {
                    if (buffer[iCnt] == 0x00)
                    {
                        tmp = System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt - iPos).Trim();
                        iPos = iCnt + 1;
                        if (tmp != "")
                            arrayList.Add(tmp);
                    }
                }
            }
            return arrayList;
        }
        // 获取指定节点的所有KEY的名称
        public ArrayList ReadKeys(string sectionName, string filePath)
        {

            byte[] buffer = new byte[5120];
            int rel = GetPrivateProfileStringA(sectionName, null, "", buffer, buffer.GetUpperBound(0), filePath);

            int iCnt, iPos;
            ArrayList arrayList = new ArrayList();
            string tmp;
            if (rel > 0)
            {
                iCnt = 0; iPos = 0;
                for (iCnt = 0; iCnt < rel; iCnt++)
                {
                    if (buffer[iCnt] == 0x00)
                    {
                        tmp = System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt - iPos).Trim();
                        iPos = iCnt + 1;
                        if (tmp != "")
                            arrayList.Add(tmp);
                    }
                }
            }
            return arrayList;
        }


        //读取指定节点下的指定key的value返回string
        public string GetIniKeyValueForStr(string section, string key, string filePath)
        {
            if (section.Trim().Length <= 0 || key.Trim().Length <= 0) return string.Empty;
            StringBuilder strTemp = new StringBuilder(256);
            GetPrivateProfileString(section, key, string.Empty, strTemp, 256, filePath);
            return strTemp.ToString().Trim();
        }
        //从指定的节点中获取一个整数值( Long，找到的key的值；如指定的key未找到，就返回默认值。如找到的数字不是一个合法的整数，函数会返回其中合法的一部分。如，对于“xyz=55zz”这个条目，函数返回55。)
        public int GetIniKeyValueForInt(string section, string key, string filePath)
        {
            if (section.Trim().Length <= 0 || key.Trim().Length <= 0) return 0;
            return GetPrivateProfileInt(section, key, 0, filePath);
        }
        //读取指定节点下的所有key 和value
        public Dictionary<string, string> GetIniSectionValue(string section, string filePath)
        {
            byte[] buffer = new byte[5120];
            int rel = GetPrivateProfileSection(section, buffer, buffer.GetUpperBound(0), filePath);

            int iCnt, iPos;
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            string tmp;
            if (rel > 0)
            {
                iCnt = 0; iPos = 0;
                for (iCnt = 0; iCnt < rel; iCnt++)
                {
                    if (buffer[iCnt] == 0x00)
                    {
                        tmp = System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt - iPos).Trim();
                        iPos = iCnt + 1;
                        if (tmp != "")
                        {
                            string[] str = tmp.Split('=');
                            dictionary.Add(str[0], str[1]);
                        }

                    }
                }
            }
            return dictionary;
        }
        /// <summary>
        /// BetLimit的读取
        /// 如果Section的key名最后带下画线就去掉下画线</summary>
        /// <param name="section"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetBetLimitSectionValue(string section, string filePath)
        {
            byte[] buffer = new byte[5120];
            int rel = GetPrivateProfileSection(section, buffer, buffer.GetUpperBound(0), filePath);

            int iCnt, iPos;
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            string tmp;
            if (rel > 0)
            {
                iCnt = 0; iPos = 0;
                for (iCnt = 0; iCnt < rel; iCnt++)
                {
                    if (buffer[iCnt] == 0x00)
                    {
                        tmp = System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt - iPos).Trim();
                        iPos = iCnt + 1;
                        if (tmp != "")
                        {
                            string[] str = tmp.Split('=');
                            str[0] = str[0].LastIndexOf("_", str[0].Length) > 0 ? str[0].Substring(0, str[0].Length - 1) : str[0];

                            dictionary.Add(str[0], str[1]);
                        }

                    }
                }
            }
            return dictionary;
        }

        //往指定section的key中写入value
        public bool WriteIniKey(string section, string key, string value, string filePath)
        {
            try
            {
                if (section.Trim().Length <= 0 || key.Trim().Length <= 0 || value.Trim().Length <= 0)
                {
                    flag = false;
                }
                else
                {

                    if (WritePrivateProfileString(section, key, value, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }
                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                flag = false;
            }
            return flag;
        }
        //修改指定section的key的值,如果找不到对应的KEY就会重新添加一个
        public bool EditIniKey(string section, string key, string value, string filePath)
        {
            try
            {
                if (section.Trim().Length <= 0 || key.Trim().Length <= 0 || value.Trim().Length <= 0)
                {
                    flag = false;
                }
                else
                {
                    if (WritePrivateProfileString(section, key, value, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }
                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                flag = false;
            }
            return flag;
        }
        //删除指定section的指定key
        public bool DeleteIniKey(string section, string key, string filePath)
        {
            try
            {
                if (section.Trim().Length <= 0 || key.Trim().Length <= 0)
                {
                    flag = false;
                }
                else
                {
                    if (WritePrivateProfileString(section, key, null, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }
                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                flag = false;
            }
            return flag;
        }
        //删除指定section
        public bool DeleteIniSection(string section, string filePath)
        {
            try
            {
                if (section.Trim().Length <= 0)
                {
                    flag = false;
                }
                else
                {
                    if (WritePrivateProfileString(section, null, null, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }
                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                flag = false;
            }
            return flag;
        }
        //给一个节点写入key和value列表
        public bool WriteIniSectionAndValue(string section, Hashtable ht, string filePath)
        {
            string lpString = "";
            try
            {
                if (section.Trim().Length <= 0 || ht.Count == 0)
                {
                    flag = false;
                }
                else
                {
                    foreach (DictionaryEntry de in ht)
                    {
                        lpString += de.Key + "=" + de.Value;
                        lpString += "\r\n";
                    }
                    if (WritePrivateProfileSection(section, lpString, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }

                }
            }
            catch (Exception e)
            {
                SystemLog.Error(e);
                flag = false;
            }
            return flag;
        }
        //给一个节点写入key 列表
        public bool WriteIniSectionName(string section, List<string> lstKeyValue, string filePath)
        {
            string lpString = "";
            try
            {
                if (section.Trim().Length <= 0 || lstKeyValue.Count == 0)
                {
                    flag = false;
                }
                else
                {
                    for (int i = 0; i < lstKeyValue.Count; ++i)
                    {
                        lpString += lstKeyValue[i];
                        lpString += "\r\n";
                    }
                    if (WritePrivateProfileSection(section, lpString, filePath) == 0)
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = true;
                    }

                }
            }
            catch
            {
                flag = false;
            }
            return flag;
        }
        #endregion
    }
}
